package inabit.data;

import java.util.ArrayList;
import java.util.List;
/**Keeps the state of the variable, if its numeric it keeps the limits of the interval
 * in which the value is limited, if it is an enumerated list, it keeps the list of values that it cannot
 * assume.
 * @author Rafael Rocha*/
public class VariableInfo {
	private List<String> differentValues;
	private Double max;
	private Double min;
	private boolean closedMax;
	private boolean closedMin;
	
	public VariableInfo() {
		differentValues = new ArrayList<String>();
	}
	
	/**Adds the string passed by parameter to the list of forbidden values*/
	public void addDifferent(String different){
		if(isValid(different)){
			this.differentValues.add(different);
		}
	}
	
	public void setLessThan(String value) {
		this.max = Double.parseDouble(value);
		closedMax = false;
	}
	public void setLessOrEqual(String value) {
		this.max = Double.parseDouble(value);
		closedMax = true;
	}
	public void setGreaterThan(String value) {
		this.min = Double.parseDouble(value);
		closedMin = false;
	}
	public void setGreaterOrEqual(String value) {
		this.min = Double.parseDouble(value);
		closedMin = true;
	}
	public Boolean isGreaterThan(Double value) {
		
		if(min != null && (min > value || (min.equals(value) && !closedMin))) {
			return true;
		}else if(max != null && (max < value || (max <= value && closedMax))) {
			return false;
		}else {
			return null;
		}
	}
	public Boolean isGreaterOrEqual(Double value) {
		if(min != null && (min > value || (min >= value && closedMin))) {
			return true;
		}else if(max != null && (max < value || (max <= value && !closedMax))) {
			return false;
		}else {
			return null;
		}
	}
	public Boolean isLessThan(Double value) {
		Boolean b = isGreaterOrEqual(value);
		if(b == null){ return null; }
		return !b;
	}
	public Boolean isLessOrEqual(Double value) {
		Boolean b = isGreaterThan(value);
		if(b == null){ return null; }
		return !b;
	}
	
	/**Returns true if the value is consistent with the information state*/
	public boolean isValid(String value) {
		if(differentValues.contains(value)) {
			return false;
		}
		if(max == null && min == null) {
			return true;
		}
		Double val = Double.parseDouble(value);
		if(min == null) {
			return closedMax? val <= max : val < max;
		}
		if(max == null) {
			return closedMin? val >= min : val > min;
		}
		return (closedMax? val <= max :  val < max) && (closedMin? val >= min : val > min);
		
	}
	
	/**Returns a list of values that cannot be assumed by the variable containing this information*/
	public List<String> getDifferentValues() {
		return differentValues;
	}

	public Double getMin() {
		return min;
	}
	public Double getMax() {
		return max;
	}

	public VariableInfo copy() {
		VariableInfo info = new VariableInfo();
		info.differentValues = new ArrayList<String>();
		info.differentValues.addAll(this.differentValues);
		info.max = this.max;
		info.min = this.min;
		info.closedMax = this.closedMax;
		info.closedMin = this.closedMin;
		return info;
	}
}
